package cn.dota2info.cglib;

import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;

import java.io.IOException;
import java.time.Duration;
import java.util.List;

public class FluxCreate {
    public static void main(String[] args) throws InterruptedException {
//        Flux<String> alphabet = Flux.just(-1, 30, 13, 9, 20)
//                .handle((i, sink) -> {
//                    String letter = alphabet(i);
//                    if (letter != null)
//                        sink.next(letter);
//                });
//
//        alphabet.subscribe(System.out::println);
//        Flux.interval(Duration.ofMillis(250))
//                .map(input -> {
//                    if (input < 3) return "tick " + input;
//                    throw new RuntimeException("boom");
//                })
//                .elapsed()
//                .retry(3)
//                .subscribe(System.out::println, System.err::println);

//        Thread.sleep(5100);

        Flux<String> converted = Flux
                .range(1, 10)
                .map(i -> {
                    try { return convert(i); }
                    catch (IOException e) { throw Exceptions.propagate(e); }
                });
        converted.subscribe(
                v -> System.out.println("RECEIVED: " + v),
                e -> {
                    if (Exceptions.unwrap(e) instanceof IOException) {
                        System.out.println("Something bad happened with I/O");
                    } else {
                        System.out.println("Something bad happened");
                    }
                }
        );
    }

    public static String alphabet(int letterNumber) {
        if (letterNumber < 1 || letterNumber > 26) {
            return null;
        }
        int letterIndexAscii = 'Z' + letterNumber - 1;
        return "" + (char) letterIndexAscii;
    }

    public static String convert(int i) throws IOException {
        if (i > 3) {
            throw new IOException("boom " + i);
        }
        return "OK " + i;
    }
}

interface MyEventListener<T> {
    void onDataChunk(List<T> chunk);

    void processComplete();
}